package jt.classic.system.listener;

import jt.classic.system.ISystem;
import jt.classic.system.ISystemException;
import jt.classic.system.objectquery.ObjectQueryItem;
import jt.classic.system.objectquery.impl.ObjectQueryItemImpl;
import jt.classic.system.tablequery.impl.TableQueryImpl;

import org.dom4j.Document;
import org.dom4j.Element;

import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;

import org.limp.basework.Column;
import org.limp.basework.SimpleBean;
import org.limp.basework.Table;
import org.limp.basework.analyzer.TableRegisterCenter;
import org.limp.basework.console.XSystemConfig;

import org.limp.mine.StringTool;

import java.io.File;
import java.io.FileFilter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/**
 * 系统监听器注册中心
 *
 * @author mido
 *
 */
public final class ListenerCenter {
    private static ListenerCenter tqc;
    private OutputFormat format;
    private List list;
    private Map info;

    /**
     * 构造函数
     *
     */
    private ListenerCenter() {
        String encoding = (String) XSystemConfig.config().getProperty(XSystemConfig.XSYSTEM_CHARSETNAME);

        this.format = OutputFormat.createPrettyPrint();
        this.format.setEncoding(encoding); //设置XML文档的编码类型
        this.format.setSuppressDeclaration(false);
        this.format.setIndent(true); //设置是否缩进
        this.format.setIndent(" "); //以空格方式实现缩进
        this.format.setNewlines(true); //设置是否换行

        this.list = new ArrayList();
        this.info = new HashMap();
    }

    /**
     * 获取静态实例
     *
     * @return TableQueryCenter
     */
    public synchronized static ListenerCenter getInstance() {
        if (tqc == null) {
            tqc = new ListenerCenter();
        }

        return tqc;
    }

    /**
     * 初始化
     *
     */
    public synchronized void init() {
        if (this.info.isEmpty()) {
            this.info.clear();
        }

        if (!this.list.isEmpty()) {
            this.list.clear();
        }

        String systemHome = (String) XSystemConfig.config().getProperty(XSystemConfig.XSYSTEM_SYSTEM_HOME);

        File folder = new File(systemHome, "conf" + File.separator +
                "listener");

        if (folder.isDirectory()) {
            File[] files = folder.listFiles(new ListenerFileFilter());

            if ((files != null) && (files.length > 0)) {
                ListenerFiles tqf = ListenerFiles.getInstance();

                for (int i = 0; i < files.length; i++) {
                    this.analyzeListenerFile(files[i]);
                    tqf.setQueryFileLastModified(files[i].getName(),
                        files[i].lastModified());
                }
            }
        }
    }

    /**
     * 重新分析配置文件
     * @param file 配置文件
     */
    public synchronized void recallListenerFile(File file) {
        ListenerFiles tqf = ListenerFiles.getInstance();
        tqf.setQueryFileLastModified(file.getName(), file.lastModified());

        try {
            SAXReader reader = new SAXReader();
            Document document = reader.read(file);

            /*object-query元素*/
            Iterator iter = document.getRootElement().elementIterator("listener");

            while (iter.hasNext()) {
                Element element = (Element) iter.next();
                IListener lis = this.initListener(element);

                this.info.put(lis.id(), lis);

                if ((this.list != null) && !this.list.isEmpty()) {
                    for (int i = 0; i < this.list.size(); i++) {
                        IListener temp = (IListener) this.list.get(i);

                        if (temp.id().equals(lis.id())) {
                            this.list.set(i, lis);
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ISystem.catchException(this, ex);
        }
    }

    /**
     * 获取监听接口实例
     * @param id
     * @return IListener
     */
    public synchronized IListener getListener(String id) {
    	IListener lis = null;

        if (this.info.containsKey(id)) {
        	lis = (IListener) this.info.get(id);
        }

        return lis;
    }

    /**
     * 分析配置文件
     * @param file 监听器配置文件
     */
    private void analyzeListenerFile(File file) {
        try {
            SAXReader reader = new SAXReader();
            Document document = reader.read(file);

            /*object-query元素*/
            Iterator iter = document.getRootElement().elementIterator("listener");

            while (iter.hasNext()) {
                Element element = (Element) iter.next();
                IListener lis = this.initListener(element);

                if (this.info.containsKey(lis.id())) {
                    throw new ISystemException(
                        "Duplicate definition of listener in [" +
                        file.getName() + "].");
                } else {
                    this.info.put(lis.id(), lis);
                    this.list.add(lis);
                }
            }
        } catch (Exception ex) {
            ISystem.catchException(this, ex);
        }
    }

    /**
     * 初始化查询接口实例
     * @param element xml element
     * @return TableQuery
     */
    private IListener initListener(Element element) throws ISystemException {
        IListener lis = new IListener();

        String id = StringTool.checkString(element.attributeValue("ID"));
        
        if(id.equals("")){
        	throw new ISystemException("listener attributeValue[id] is invalid.");
        }
        
        String name = StringTool.checkString(element.attributeValue("className"));
        
        if(name.equals("")){
        	throw new ISystemException("listener attributeValue[className] is invalid.");
        }
        
        String desc = StringTool.checkString(element.attributeValue("desc"));

        lis.getResource().put("id", id);
        lis.getResource().put("name", name);
        lis.getResource().put("desc", desc);

        lis.reload(null);

        return lis;
    }

    /**
     * 监听器注册文件过滤器
     * @author mido
     *
     */
    private class ListenerFileFilter implements FileFilter {
        /**
        *
        * 文件类型过滤
        * @param file 注册文件
        * @return boolean
        *
        */
        public boolean accept(File file) {
            if (file.isFile()) {
                /*文件名称*/
                String fileName = file.getName();

                /*文件扩展名*/
                String expandName = ((fileName.lastIndexOf(".") > -1) &&
                    (fileName.lastIndexOf(".") < fileName.length()))
                    ? fileName.substring(fileName.lastIndexOf(".") + 1) : "";

                return expandName.equals("lis");
            }

            return false;
        }
    }
}
